home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-10-17 | 46.9 KB | 1,193 lines |
- STDWIN -- STANDARD WINDOWS
- --------------------------
- RATIONALE
- ---------
-
- STDWIN was born by the desire to make using windows both easier and more
- portable for a certain class of applications. To show why it should be
- easier than it currently is, consider for example the calls necessary to
- create a window on the Apple Macintosh:
-
- WindowPtr w;
- Rect r;
-
- SetRect(&r, <desired window coordinates>);
- w= NewWindow(
- (Ptr)nil, /* Optional storage */
- &r, /* Initial position/size */
- documentProc, /* Border frame type */
- "Untitled", /* Title */
- true, /* Immediately visible */
- 0L, /* Reference constant */
- (WindowPtr)-1 /* Behind no other window */
- );
-
- Since I'm doing this without documentation, I may have missed or
- reversed some parameters, which shows exactly what I want to illustrate:
- the call has too many options, most of which are of no interest to most
- application programmers. Also, it forces the programmer to invent an
- initial position for the window, which is often a burden, since this
- means one also has to invent a scheme by which to offset the position
- for subsequent windows, to avoid creating windows that overlap exactly.
-
- What this example doesn't show is the amount of code one has to write
- to provide the functionality that Mac users expect from even the
- simplest application: windows can be moved, resized, zoomed, closed,
- (de)activated, scrolled in two directions, and need to be explicitly
- redrawn when they pop up from below another window; none of this is done
- automatically by the window manager. One needs hundreds of lines of
- code to provide all this functionality, and most of it has to be
- interspersed with application-dependent code (such as to actually draw a
- window's contents), which makes it harder to reuse the same code in the
- next program one writes.
-
- There are other burdens to the application programmer who writes for the
- Macintosh, such as the large number of #include files that one must put
- in even the simplest programs, and the correspondingly large number of
- initialization calls one must make.
-
-
- Why using windows should be made more portable is clear if one considers
- what is necessary to port a program to a different machine like the
- Atari ST, the Commodore Amiga, or a Sun/3 running Suntools or X Windows
- (while all these use the same type of processor!). Not only are the
- calls that interface to their window managers different, the semantics
- of windows are also subtly different. Some systems remember a window's
- contents when it is covered by another window, so 'update events' are
- unheard of; some systems provide a standard interface to scroll bars or
- other tools; etc., etc.
-
- This seriously limits productivity of application programmers: it can
- take many person-months to port a successful program to a new machine,
- even though one has used a high-level programming language such as C or
- Pascal. While this effort may be economically justifyable for
- bestsellers like commercial spreadsheets or wordprocessors, there is a
- large class of applications where one can simply not afford these
- porting efforts, especially in the academic world, but also for many
- specialized applications which aim at a more limited market.
-
-
- The current design places an emphasis on full-function windows that give
- a scrollable 'view' on some kind of two-dimensional document, e.g. a
- program text editor or a graphics design program. It provides some
- tools for simple modal input (e.g., to ask for a string or a file name)
- and gives a clean but powerful interface to the common types of pop-up
- or pull-down menus (with text items only). What is clearly missing is a
- mechanism to put indicators, icons, controls, rulers, palettes, tool
- wells and other gadgets in the window border or on the 'desktop', and
- the ability to pop up a collection of gadgets in a dialog window as
- commonly seen on the Mac. Suggestions for a general mechanism here
- which fits in STDWIN's philosophy are welcome. (Are there any other
- systems besides the Macintosh and its derivatives like the ST or the
- Amiga that provide tools for controls and dialogs?)
-
- I haven't placed too much emphasis on the design of the graphics
- primitives that must be used to draw the contents of a window. There
- are simple routines to draw text strings in a single proportionally
- spaced font with a few stylistic variations, and to do simple line
- drawings and a few rasterop operations on rectangles. I plan to extend
- the repertoire (and to implement defined functions) as the need arises;
- ideally, a standard such as GKS should be adopted, if we want fo
- accommodate applications with more drawing requirements. The is nothing
- in the interface definition which precludes color drawing.
-
- Although the documentation clearly describes the interface to a library
- of C functions, it shouldn't be to hard to translate the interface to
- other languages like FORTRAN or Modula. Ideally, STDWIN should be
- defined as a set of 'abstract' functions for which language bindings can
- be provided, similarly to the definition of GKS.
-
- --- Postscript ---
-
- The general aim of STDWIN is to provide high-level features to
- applications which can be used with little effort. Features provided
- must be implementable on top of a large number of window managers;
- therefore, no precise definitions of some semantical aspects of windows
- can be given, in order not to rule out certain implementations (example:
- there can be no mention of a 'stack' of windows, since we want to be
- compatible with tiling window managers). This may impair the freedom of
- applications, but will enforce a useful standardization of applications
- running on a particular system.
-
- In many cases STDWIN provides a way to change the default behaviour
- if this is considered useful for the application; sometimes such
- default-changing routines have an optional or approximate effect,
- depending on whether they can be implemented on a particular system.
- For best effect this may require some system-dependent tuning when an
- application is ported.
-
- DEFINITIONS OF TERMS
- --------------------
-
- Here are short definitions of many of the terms used in the descriptions
- below. Not all of these definitions are as precise as they could or
- should be. Suggestions for improvement (also about the order of
- presentation) are welcome.
-
- Window
- A (usually) rectangular area on the screen which contains a view
- on a document. A window is linked to one particular document;
- it has a title and 'borders', which usually contain scroll bars,
- a grow box and possibly other controls and indicators. The end
- user may usually change a window's position and size, as well as
- the part of the document onto which the window gives a view.
-
- Document
- The (abstract) data structure onto which a window gives a view.
- A document is a rectangular portion of the plane, with maximum h
- and v coordinates which can be set by the application, but it is
- NOT a bitmap: a document may be much larger than the largest
- bitmap that fits in main memory, and it is defined by a 'draw
- procedure'.
-
- Window tag
- A small (16-bit) integer used to distinguish windows. It is set
- by the application.
-
- Draw procedure
- The function that defines a document. When called with the
- coordinates of a rectangle, it should draw (at least) that part
- of the document that lies within this rectangle, using the
- drawing primitives provided by STDWIN, e.g. wdrawline()
- and wdrawtext().
-
- Document coordinates
- All coordinates passed to and from STDWIN functions use a
- coordinate system called 'document coordinates'. These are
- derived through translation from window or screen coordinates:
- the origin of the document is called (0, 0), independent of its
- position on the screen or in the window. This origin is
- positioned in the UPPER left corner of the document, with the
- positive horizontal (h) axis pointing right and the positive
- vertical (v) axis pointing DOWN. Document coordinates are
- specified as integers.
-
- Pixels
- Are the units of measurement of document (and other)
- coordinates. The size of a pixel is system-dependent; on most
- screens it is equal to a screen pixel, but on alphanumeric
- displays it equals a character. There is no guarantee that the
- physical width and height of a pixel are the same; i.e., a
- rectangle with equal width and height measured in pixels need
- not look square on the screen.
- The term pixel is also used to refer to a black or white dot on
- the screen.
-
- Text attributes
- The set of parameters that affect the appearance of characters
- drawn on the screen with wdrawtext() and friends. This may
- include font (e.g., Times), stylistic variation (e.g., Italic),
- point size (e.g., 12), and other variations such as underlining
- and inverse video. The exact set of parameters used is
- system-dependent. Text attributes are used both by the text
- drawing functions and by the text measuring functions; the
- latter allow an application to calculate the size of a text
- string or paragraph before it is drawn.
-
- Text caret
- Each window can have an associated 'text caret'. This is an
- indicator of where the next character would be inserted. Its
- appearance is system-dependent; on alphanumeric displays it is
- usually a blinking square or underline positioned at the next
- character position; on bitmapped displays it is usually a
- blinking vertical line just before the next character position.
- There is at most one text caret per window; only the active
- window's caret blinks (or is visible at all).
- (The name 'caret' is used instead of 'cursor' because the latter
- word also refers to the arrow or other symbol moved by the
- mouse. The name seems to be taken from the symbol actually used
- for its function in Smalltalk-80, which looks like a '^' at the
- baseline pointing at the insert position between two characters.)
-
- Event
- Any form of interactive input to the application, reported by
- wgetevent(). Events include keys pressed on the keyboard, menu
- selections, mouse clicks, but also the fact that a new window
- has become 'active'.
-
- Active window
- The window to which most events apply. It is usually displayed
- with a special highlighting of its border or title, and on
- overlapping window systems it is usually the frontmost window,
- and thus visible in its entirety. At any time there is at most
- one active window. The application has little or no influence
- over which window is active, since the end user may randomly
- select a window and activate it. In a multi-programming
- environment, where the screen is shared by several applications,
- at most one application has an active window, and only this
- application will receive keyboard events.
-
- CONVENTIONS
- -----------
-
- For the benefit of the user of the STWIN library there are some
- conventions about naming of functions, parameter order and so on; these
- also restrict and guide the design of further additions to the library
- (without restricting the expressive power; they are just conventions of
- form).
-
- - Names of functions, parameters, variables, structure tags and
- structure members are written in lower case.
- - Type names and constants are written in UPPER CASE.
- - Underscores are not used in names, except in defined constants.
-
- - Names of structured types are written in upper case, e.g. WINDOW,
- EVENT. Such names always denote the struct itself; pointer types are
- made by appending an asterisk, e.g. WINDOW *.
- - All functions (except the textedit package) have a name beginning with
- 'w'.
- - Enquiry functions have a name beginning with 'wget'; corresponding
- changing functions begin with 'wset'.
-
- - Standard abbreviations (used in function and parameter names):
- 'attr' attribute
- 'bool' boolean
- 'buf' buffer
- 'def' default
- 'doc' document
- 'h' horizontal
- 'len' length (of a string)
- 'pos' position
- 'scr' screen
- 'str' string
- 'v' vertical
- 'win' window
- - When a word has an abbreviation, the abbreviation should be used
- consistently.
- - Most other words are written unabbreviated.
-
- - Coordinates are given in the order (horizontal, vertical); sizes in
- the order (width, height). Distances are given as (dh, dv).
- - Rectangles are given as (left, top, right, bottom). The pixels at the
- right and bottom borders are not contained in the rectangle. I.e.,
- the rectangle (0, 0, 0, 0) contains no pixels; the rectangle
- (0, 0, 1, 1) contains one pixel, at position (0, 0).
- - Angles [how are these defined - gbl]
-
- - When a function has a window pointer as parameter, it is the first
- parameter.
- - When a function has a string parameter and a length of the same, the
- length parameter immediately follows the string parameter. A negative
- length indicates that the string's length is to be computed by
- strlen() (this should work in all such cases).
- - When a function has one or more output parameters, these parameters
- (of type 'pointer to ...') have a name beginning with 'p', e.g.
- pwidth, pheight.
- - When a function has a struct as parameter, its address is passed,
- even if only its value is used. [This rule is in part based on the
- old C standard, which has shaped common practice amongst C
- programmers, in part on efficiency considerations.]
-
- The textedit package has some private conventions:
-
- - All textedit function names start with 'te'.
- - The pointer to the TEXTEDIT structure is the first parameter.
-
- DATA STRUCTURES
- ---------------
-
- The following data structures are defined in <stdwin.h>.
-
- WINDOW *
- A pointer to a WINDOW structure, whose contents is
- implementation-defined. It is used to identify the window that
- an operation applies to.
-
- TEXTATTR
- struct textattr {
- ...
- };
- An implementation-defined structure containing all parameters
- to the text drawing and measuring functions.
-
- EVENT
- struct event {
- ...
- int type;
- int window;
- union {
- int character;
- int command;
- struct {
- int h;
- int v;
- int clicks;
- int button;
- int mask;
- } where;
- struct { int id; int item; } m;
- struct { int left, top, right, bottom; } area;
- ...
- } u;
- ...
- };
- A structure with mostly well-known members (although their
- types may differ slightly, e.g. short or unsigned instead of
- int, and more members may be actually present). It contains
- information about an `event'.
-
- TEXTEDIT
- struct textedit {
- ...
- char *text;
- int foc1, foc2;
- int left, top, right, bottom;
- int nbreaks;
- ...
- };
- A structure with some well-known and some private members. It
- contains sufficient information for the `textedit' package to do
- simple editing operations on the text. [Note: the well-known
- members should really be hidden as well, and accessed only
- through access functions!]
-
- MENU *
- A pointer to a menu definition. It is returned by wmenucreate()
- and used to refer to the menu in all further calls that affect a
- particular menu, e.g. wmenuadditem().
-
- LIMITATIONS
- -----------
-
- - STDWIN library functions don't check their arguments for illegal
- values, such as NULL or invalid window pointers or NULL string
- pointers. Such parameters are in error and may cause crashes or other
- strange behaviour. An exception is made for coordinates: these are
- clipped to the valid drawing area, if necessary.
- - The STDWIN library makes freely use of statically allocated data; it
- is not reentrant. Signal handlers should not call longjmp (and
- neither should draw procedures), nor any STDWIN function, when it is
- possible that a STDWIN function is already active. An exception is
- wdone(), which may be called from a signal handler at any time (even
- before winit() is called or while it is executing), provided no more
- calls to STDWIN follow and the handler termiates the program in some
- way (e.g., by calling exit() or abort()). (In return, the STDWIN
- library will not call the draw procedure except from wgetevent().)
- - Most functions do not report any error condition. If they can't
- perform their function due to some semantic constraint, they just do
- nothing. Functions that return pointers will return NULL pointers
- in such cases. Similar for out-of-memory conditions; these will not
- cause immediate crashes but are not reported back directly either.
- (It will be possible to substitute one's own memory allocator which
- could set an error flag when it detects a memory shortage; there
- should also be a user function to be called whenever an error is
- detected.)
- - STDWIN functions may actually be implemented as macros. It is not
- guaranteed that the arguments are evaluated exactly once!
- - The current versions of the library has many external names that
- shouldn't be visible to the application, or at least should start with
- an unlikely combination such as '_w_'. My apologies. This'll change
- eventually.
-
- USAGE
- -----
-
- [NOTE: the information in this section is out of date; the versions
- described here are ancient!]
-
- All definitions for the STDWIN library are contained in the header file
- <stdwin.h>. All routines are to be found in compiled form in the
- library file "libstdwin.a". These reside in system-dependent
- directories; you might try the following options to cc (on boring and
- tango):
-
- G=~guido
- cc -I$G/include <files> $G/lib/libstdwin.a
-
- This gets you the termcap version on boring, but the true windowing
- version on tango.
-
- ROUTINES
- ========
-
- The following routines are available to the application programmer.
- Routines marked with [*] are not available in the first
- implementation(s).
-
-
- INITIALIZATION
- --------------
-
- void winitnew( &argc, &argv );
- Initializes the STDWIN library. Required before any STDWIN
- calls. Should be called only once per program run. The pointers
- to argc and argv allow some implementations of STDWIN to grab
- command line arguments without the program knowing.
-
- void wdone();
- Ends use of the STDWIN library. Removes open windows and resets
- any special system state set by STDWIN. Required once winit()
- has been called; safe to call before winit() has been called.
- Also safe to call within signal handlers.
-
- SCREEN PROPERTIES
- -----------------
-
- void wgetscrsize(int *pwidth, *pheight);
- Reports the size of the screen in pixels. This is usually
- larger than the largest window size, since windows have borders.
-
- void wgetscrmm(int *pmmhor, *pmmvert);
- Reports the approximate size of the screen in millimeters. This
- may be used to scale documents to true life size, or to
- determine the screen's aspect ratio. Note that this information
- may be unavailable or inaccurate; if unavailable, the size of an
- average monitor is reported.
-
-
-
- WINDOW CREATION
- ---------------
-
- WINDOW *wopen(char *title, void (*drawproc)());
- Opens a window. Displays the title in the window border. The
- draw procedure is remembered for later use to process window
- refreshes. Returns a pointer to the window structure. The
- window becomes the active window (this will normally cause a
- WE_ACTIVATE event the next time wgetevent() is called). The
- content area of the window will be redrawn (by calling the draw
- procedure) by a call to wgetevent() in the near future. The
- window receives the current default text attributes as its
- text attributes. Passing a NULL pointer as the drawproc changes
- the treatment of window redrawing: whenever part of a window
- must be redrawn, a WE_DRAW event is generated.
-
- void wclose(WINDOW *win);
- Disposes of a window and associated data structures. Some other
- window may become the active window (and a WE_ACTIVATE event is
- then generated).
-
- void wupdate(WINDOW *win);
- Causes the window's content area to be redraw (by calling its
- draw procedure) insofar as necessary. This may be used to show
- changes in a document without calling wgetevent(); it is called
- automatically by wgetevent() for all open windows (with non-NULL
- draw procedures) when that routine finds no other immediate
- events.
-
-
- WINDOW DEFAULT PROPERTIES
- -------------------------
-
- These functions should be called before wopen() if they are to have the
- desired effect. Calling them with specific parameters before each call
- to wopen() gives an application precise control over window properties
- (if the STDWIN implementation allows it).
-
- void wsetdefwinsize(int width, height);
- Sets the initial size of any windows created subsequently. This
- request may be ignored or have an approximate effect only,
- depending on the STDWIN implementation.
-
- void wsetdefwinpos(int h, v);
- Sets the initial position of the top left corner of any
- windows created subsequently (in screen coordinates). Same
- restrictions as for wsetdefwinsize() above apply. Moreover,
- the window creation process may try to avoid creating windows
- that overlap completely, by offsetting the default position
- slightly after each window is created.
-
- void wsetmaxwinsize(int width, height);
- Sets the maximum size of any windows created subsequently. This
- may be important for certain STDWIN implementations where memory
- proportionally to the maximum window size is allocated for a
- window when it is created. Same restrictions as for
- wsetdefwinsize() above apply. It is not possible to change a
- window's maximum size once it has been created. {I wish this
- restriction were not necessary, but the Whitechapel requires
- allocation of a bitmap of the maximum window size when a window
- is created, unless I have overlooked something in the
- documentation. The screen size is 1K x 1K pixels, which would
- require a 128K bitmap!}
-
- [Note: if an implementation has other properties for windows that an
- application might want to set a default or a specific value for each
- window, there should be similar functions to set such values.
- Preferably a standard should emerge for such properties.]
-
-
- WINDOW ACTIVATION
- -----------------
-
- void wsetactive(WINDOW *win);
- Changes the active window to the specified window. This allows
- the application (instead of the user) to choose the active
- window. You do not need to call this function in response to
- a WE_ACTIVE event; it is done automatically.
-
- WINDOW *wgetactive();
- Returns a pointer to the current active window.
-
- WINDOW PROPERTIES
- -----------------
-
- void wsettag(WINDOW *win, short tag);
- Sets a window's 'tag' to the specified value. This is a field
- that the application can set to any 16-bit value; probably the
- best use one can make of it is to use it as a 'document index'
- so a program with multiple windows can find its own data
- structures belonging to a particular window. The initial value
- is zero. Note that it is a 16-bit value to discourage storing a
- pointer in it (which would introduce a serious portability
- problem on machines where pointers are larger than the largest
- size integer).
-
- short wgettag(WINDOW *win);
- Returns the window's 'tag', as set by the last call to wsettag()
- for this window. This is often a macro, so you needn't worry
- about its speed.
-
- void wsettitle(WINDOW *win, char *title);
- Displays a new title in the window's border.
-
- void wgetwinsize(WINDOW *win, int *pwidth, *pheight);
- Reports the width and height of the window's contents area.
- (that's the part of the document that's visible, not the entire
- document!)
- (Note that most window managers allow the user to resize a
- window, so this information is only valid for a limited time.
- WE_SIZE events make it possible to keep track of a window's size
- changes.)
-
- void wgetwinpos(WINDOW *win, int *ph, *pv); [*]
- Reports the position of the window's upper left corner relative
- to the screen's upper left corner. Same remarks as wgetwinsize().
- [ Why isn't this a macro? - gbl ]
-
- void wgetwinorigin(WINDOW *win, int *ph, *pv); [*]
- Reports the position of the window's upper left corner in
- document coordinates [i.e., an indication for the position of
- the scroll bars]. Same remarks as wgetwinsize().
-
- [Should there be corresponding functions wsetwinsize, wsetwinpos etc.?]
-
-
- DOCUMENT CONTENTS
- -----------------
-
- void wsetdocsize(WINDOW *win, int width, height);
- Tells the size of the document; this is needed so that the
- window manager can put up proper scroll bars. When not set,
- the document size is assumed to be equal to the maximum window
- size.
-
- void wchange(WINDOW *win, int left, top, right, bottom);
- Tells the STDWIN library that the indicated rectangle of the
- document needs to be redrawn. The actual redraw is delayed
- until the first call to wupdate() for the window, or a call to
- wgetevent() that doesn't find a high priority event in its
- queue.
-
- void wsetorigin(WINDOW *win, int h, v);
- Moves the view that the window gives on the document so that the
- point (h, v) is displayed in the upper left corner of the
- window. (h, v) are clipped to lie within the document.
-
- void wshow(WINDOW *win, int left, top, right, bottom);
- Tries to scroll the window to put the given rectangle on the
- screen.
-
- void wscroll(WINDOW *win, int left, top, right, bottom, int dh, dv);
- Scrolls the given rectangle by the amount (dh, dv). No pixels
- outside the rectangle are affected; pixels scrolled out are
- lost, pixels scrolled in are erased. This may be replaced by a
- call to wshow with the same values for the first 5 parameters.
-
-
- TEXT ATTRIBUTES
- ---------------
-
- [Certain bits of information are repeated here over and over. How to
- avoid this?]
-
- void wgetwintextattr(WINDOW *win, TEXTATTR *attr);
- Retrieves the window's text attributes. There is not much one
- can do with these except pass them to wsetwintextattr() and
- wsettextattr().
-
- void wsetwintextattr(WINDOW *win, TEXTATTR *attr);
- Changes the window's text attributes. A window's text
- attributes are used to initialize the (global) default
- attributes when its draw procedure is called.
-
- The following functions have a double meaning: when called from outside
- a draw procedure, they affect the global default text attributes; when
- used within a draw procedure (when it is called from wgetevent()), they
- affect the current text attributes, that are also used by wdrawtext()
- and the text measuring functions. These current text attributes are
- initialized to the window's text attributes before the draw procedure
- is called; but the window's text attributes are not restored from the
- final value of the current text attributes (to change a window's text
- attributes, use wsetwintextattr()).
-
- To change a window's text attributes, one could do the following
- (outside the draw procedure):
-
- TEXTATTR saveattr, winattr;
- wgettextattr(&saveattr); /* Save current default attrs */
- wgetwintextattr(&winattr); /* Get window's attrs */
- wsettextattr(&winattr); /* Use them as new current attrs */
-
- wsetbold(); /* Or whatever; change current attrs here */
- ...
-
- wgettextattr(&winattr); /* Get changes attrs */
- wsetwintextattr(&winattr); /* Store them in the window */
- wsettextattr(&saveattr); /* Restore saved defaults */
-
- [Sorry if this looks complicated. It's easier to change the defaults
- before you create the window...]
-
- void wsetplain();
- void wsetbold();
- void wsetitalic();
- void wsetbolditalic();
- void wsethilite();
- void wsetinverse();
- void wsetunderline();
- These functions select the text drawing style. Setplain()
- resets the style to default; the others (attempt to) select a
- particular alternate style. At least one alternate style is
- available. When a particular alternate style is unavailable,
- another alternate style (but not plain) is chosen. Wsethilite
- chooses an alternate style that is particularly suitable to the
- given screen.
-
- void wsetfont(char *font); [*]
- void wsetpointsize(int size); [*]
- [Is this a reasonable interface to select fonts? E.g.
- wsetfont("times");
- wsetpointsize(12);
- Or is it better to combine the two, e.g.
- wsetfont("times", 12);
- Is there a need for non-integral point sizes? I've heard about
- phototypesetters that have half-point size increments...]
-
- void wgettextattr(TEXTATTR *attr);
- Report the current text attributes. These are the global default
- text attributes when called from outside a draw procedure, the
- current drawing text attributes inside a draw procedure.
-
- void wsettextattr(TEXTATTR *attr);
- Set the current text attributes (from a value previously
- retrieved with wgettextattr() or wgetwintextattr()). Same
- remark as for wgettextattr().
-
-
- TEXT MEASURING
- --------------
-
- The text measuring functions can be used inside or outside a draw
- procedure. Outside, they use the global default text attributes;
- inside, they they use the current text attributes (initialized from the
- window's text attributes).
-
- int wlineheight();
- Returns the height, in pixels, of a text line in the current
- font, style and point size. This includes the ascent, descent
- and extra line spacing, so that text lines whose baselines or
- top lines differ by this much look 'right' (you may have a
- different opinion, though).
-
- int wtextwidth(char *str, int len);
- Returns the width (in pixels) of the string 'str', of length
- 'len', when it would be drawn using the current text attributes.
- Note that the width of a string may differ (slightly) from the
- sum of the widths of its characters, due to kerning and other
- magic that goes on during character drawing. Different selected
- text styles or other attributes also affect the outcome. It is
- guaranteed, however, that wtextwidth() gives the same result as
- the width reported (implicitly) by wtextdraw() using the same
- text attributes.
-
- int wcharwidth(char c);
- Similar to wtextwidth(), but for one character.
-
- int wtextbreak(char *str, int len, int width);
- Returns the number of characters string string 'str', of length
- 'len', that would fit in 'width' pixels, when drawn with the
- current text attributes. (This is useful when trying to break
- the lines of a paragraph of text, for instance; this call is
- faster than repeated calls to wtextwidth() until the given width
- is exceeded.)
-
-
- THE DRAW PROCEDURE
- ------------------
-
- The draw procedure that was passed as a parameter to wopen() is called
- by wgetevent() when it needs to refresh part of the document. It should
- be declared as follows:
-
- void drawproc(WINDOW *win, int left, top, right, bottom);
-
- The draw procedure should draw at least that part of the document that
- lies within the given rectangle (in document coordinates). It may draw
- more, even all of the document, but this may slow down the drawing
- process considerably. It can use the drawing operations described
- below, the text measuring functions and the text attribute functions
- described above, and the window and screen property enquiries described
- far above. It should not call any other STDWIN functions.
-
- DRAWING OPERATIONS
- ------------------
-
- Before calling any of the drawing primitives from outside of a drawing
- procedure, the application should call wbegindrawing() to signal which
- window it is drawing in. Output will not be flushed to the process
- until a corresponding call to wendrawing(), or a call to wflush().
- A drawing procedure being called by STDWIN will have this done
- automatically.
-
- void wbegindrawing(WINDOW *win);
- Signals start of drawing.
-
- void wendrawing( WINDOW *win);
- Signals end of drawing, and flushes output to window.
-
- void wflush(); [*]
- Flushes output during drawing.
-
- Note: none of following operations is currently implemented in the termcap
- version, and most will probably remain dummies anyway.
-
- void wdrawline(int h1, v1, h2, v2);
- Draws a line from (h1, v1) to (h2, v2). Specifying h1==v1 and
- h2==v2 plots a point.
-
- void wxorline(int h1, int v1, int h2, int v2);
- Draws a line from (h1, v1) to (h2, v2), inverting all points
- in the line, such that pixels which were previously dark are
- now light and vice-versa.
-
- void wdrawbox(int left, top, right, bottom);
- Draws a rectangular box that lies just *inside* the given
- rectangle. Don't call with left >= right or top >= bottom.
-
- void wdrawcircle(int h, v, radius);
- Draws a circle with center (h, v) and given radius.
-
- void werase(int left, top, right, bottom);
- Erases the given rectangle.
-
- void wpaint(int left, top, right, bottom);
- Paints the given rectangle black.
-
- void wshade(int left, top, right, bottom, int percentage);
- Shades the given rectangle with a colour grey that approximates
- the given percentage; 0 is white, 100 is black. Unlike
- werase(), wshade() does not clear any pixels, it just adds black
- pixels; so lightly shading an area where a text has already been
- drawn gives the effect of text on a shaded background. (The
- reverse drawing order also works.)
-
- void winvert(int left, top, right, bottom);
- Inverts the pixels in the given rectangle.
-
- void wdrawelarc(int h, int v, int radh, int radv,
- int angle1, int angle2);
- Draws an elliptical arc, with axes parallel to the horizontal
- and vertical axes, starting drawing at angle1 and ending
- drawing at angle2.
-
-
- TEXT DRAWING OPERATIONS
- -----------------------
-
- The following routines, like the drawing primitives above, may only be
- used from within a draw procedure or between calls to wbegindrawing()
- and wenddrawing().
-
- int wdrawtext(int h, v, char *str, int len);
- Draws the text string 'str' of length 'len' starting with its
- upper left corner at (h, v). Returns the h coordinate of the
- upper right corner of the drawn text. Explanation:
-
- initial (h, v):
- |
- v w
- *-------------------------------------------------------* } l
- | | } i
- | ######### ######### ####### ####### ######### | } n
- | # # # # # # | } e
- | ####### ####### ####### ###### # | }h
- | # # # # # # | } e
- | ######### ######## # # ####### # | } i
- | | } g
- *-------------------------------------------------------* } h
- ^ t
- |
- return h coordinate of this point:
-
- int wdrawchar(int h, int v, char c);
- Similar to wdrawtext(), but draws one character.
-
-
- THE TEXT CARET
- --------------
-
- void wsetcaret(WINDOW *win, int h, v);
- Declares that the window's "text caret" is to be positioned at
- position (h, v). The caret is placed such that it appears just
- before a character drawn at this position. Depending on the
- possibilities of the hardware, the caret may blink. There can
- be at most one text caret per window.
-
- void wnocaret(WINDOW *win);
- Removes the window's text caret.
-
-
- EVENTS
- ------
-
- void wgetevent(EVENT *ep);
- Waits until the next event is available, then places
- information about it in the EVENT struct pointed by 'ep' and
- returns. When no event is available immediately, it redraws
- any windows that still need redrawing (as indicated by a call
- to wchange() or other causes such as windows being moved by the
- user) by calling wupdate() which will call their draw procedure.
- It also handles menu selection, window moving and resizing and
- scrolling.
-
- Event types are the following:
-
- WE_ACTIVATE
- A window becomes active. The 'window' field of the EVENT
- struct indicates what window. If this contains NULL, no
- window belonging to the application is active; this is
- possible in multi-process environments.
-
- WE_CHAR
- A character has been typed on the keyboard. Its ASCII
- value can be found in the field 'u.character'.
-
- WE_COMMAND
- A special command has been issued, usually by pressing a
- special key or clicking some icon. Codes found in the
- field 'u.command' are:
-
- WC_CLOSE
- Request to close a window. Which window can be
- found from 'e.window'.
-
- WC_LEFT, WC_RIGHT, WC_UP, WC_DOWN
- Arrow key pressed.
-
- WC_CANCEL, WC_BACKSPACE, WC_TAB, WC_RETURN
- Special key pressed.
-
- There may be other codes depending on the STDWIN
- implementation.
-
- WE_MOUSE_DOWN
- The mouse button was pressed. The position (expressed
- in document coordinates) can be found in the 'u.where'
- field, subfields 'h' and 'v'. The 'clicks' subfield
- indicates whether this event is or may be part of a
- multi-click sequence; its value is N if this click is
- the N-th click in a multi-click sequence; N is at least
- 1.
-
- WE_MOUSE_MOVE
- The mouse pointer was moved. This event is only
- reported when the mouse button is down. The new
- position can be found in the 'u.where' field. The
- 'clicks' subfield is always zero.
-
- WE_MOUSE_UP
- The mouse button was released. This event is only
- reported when the mouse button was previously down (but
- it is not guaranteed that a WE_MOUSE_UP event will ever
- follow when a WE_MOUSE_DOWN event is reported). The
- position can be found in the 'u.where' field. If this
- click was the N-th click in a multi-click sequence, the
- 'clicks' field contains N; otherwise it is 0.
-
- WE_MENU
- A menu item was selected. The menu id and item can be
- found in the fields 'u.m.id' and 'u.m.item'.
-
- WE_SIZE
- A window's size has changed. The affected window can be
- found in the field 'window'. The window's new size can
- be requested by calling wgetwinsize().
-
- WE_TIMER
- A window's timer has expired.
-
- A STDWIN application may define more events with an
- implementation-dependent meaning. It may also define additional
- implementation-dependent fields in the EVENT struct. Most
- applications should refrain from using these.
-
- void wsettimer(WINDOW *win, int deciseconds);
- Sets a window's timer to go off in a given number of tenths
- of a second. A WE_TIMER event will be delivered for that window
- after the timer goes off. A window has only one timer; each
- succeeding call overrides the previous value. A deciseconds
- value of 0 turns the timer off. The largest decisecond value
- guaranteed to be supported is 32000.
-
-
- MENUS
- -----
-
- There are two kinds of menus: 'global' and 'local' menus. Global menus
- are available independent of which window is active; local menus must
- explicitly be attached to one or more windows, and are only available if
- they have been attached to the currently active window. By default, all
- windows created are global; this can be changed by calling
- wmenusetdeflocal(TRUE). Most systems have fairly low limits on the
- number and size of menus; 5 to 10 menus of 10 to 20 items can usually
- be accommodated.
-
- MENU *wmenucreate(int id, char *title);
- Creates a new menu with the given menu id and title. The id is
- used to report menu selection events for this menu, see
- wgetevent() above, subsection WE_MENU. The id should be in the
- range [1..255], and differ from all other menu ids in use.
- Initially, the menu contains no items. It returns a pointer to
- the menu definition, which should be used in all subsequent
- calls that affect this menu; a NULL pointer is returned if the
- menu couldn't be created.
-
- int wmenuadditem(MENU *menu, char *text, int shortcut);
- Adds an item to the menu. The item's item number is one
- higher than the highest item already in the menu; the first
- item gets number zero. This item number is the return
- value. Some systems interpret various punctuation characters
- in the text as special flags, so it is best to limit the
- text to alphanumeric characters and space. The item may
- have a keyboard shortcut; shortcuts are usually implemented
- by using an extra shift modifier ('ALT' or 'META' key) or
- a prefix such as 'ESC'. If no shortcut is desired, -1
- should be passed for this parameter, otherwise a positive
- ASCII code should be passed.
- Items cannot be removed or reordered from a menu, nor can their
- shortcuts be changed; an item's text chan be changed, see
- below.
- Adding an empty string to a menu creates an empty, unselectable
- item, which may serve to separate groups of items in a long
- menu.
-
- void wmenusetitem(MENU *menu, int item, char *text);
- Changes the text of the item to the new text. The parameter
- 'item' must be the item number of an existing item in the menu.
- A conventional way to temporarily disable a menu item is to set
- its text to the empty string; it can be enabled again by
- setting the text back to what it originally was.
-
- void wmenudelete(MENU *menu);
- Deletes the menu. If it is a local menu, it is detached from
- all windows to which it was attached. All storage associated
- with the menu is released.
-
- void wmenuattach(WINDOW *win, MENU *menu);
- Attaches a local menu to a given window. This makes the menu
- available whenever the window is active. A menu may be attached
- to as many windows as desired. Don't use this for global menus.
-
- void wmenudetach(WINDOW *win, MENU *menu);
- Detaches a local menu from a given window. No effect for global
- menus.
-
- void wmenusetdeflocal(bool local);
- Sets the default status for subsequently created menus.
- Initially, all menus created will be global.
-
-
- DIALOG TOOLS
- ------------
-
- The following functions are available for simple dialogs that ask a
- yes/no question or request a file name, and a few more.
-
- void wmessage(char *str);
- Puts up an error message. This may be put in a separate box in
- front of all other windows and require some user action before
- it goes away; or it may be placed in a less conspicuous position
- but stay there for a while. When a second message is issued,
- the first is generally overwritten.
-
- bool waskstr(char *prompt, char *buf, int buflen);
- Asks the user to type a text string. The string is placed in
- buffer 'buf' of length 'buflen'; 'buf' is guaranteed to be
- zero-terminated. The initial content of 'buf' is used as a
- default reply. The user has the possibility to cancel the
- interaction, in which case the function returns FALSE (and buf
- is left undefined).
-
- Cancellation is implemented in a system-dependent manner; if a
- system has a conventional 'interrupt' key or key combination,
- this is generally used. On Unix systems the interrupt character
- as set by 'stty' is used.
-
- [*] Current implementations ignore the given buffer length. The
- buffer should be at least 256 bytes long.
-
- int waskync(char *question, int def);
- Asks a question to which a yes/no answer is applicable. The
- user may also cancel the interaction. Return values are: 1 for
- yes, 0 for no, -1 for cancelled. The parameter 'def' is the
- default reply (chosen when the users presses return without
- typing anything) and should also be one of -1, 0 or 1, with the
- same meaning.
-
- bool waskfile(char *prompt, char *buf, int buflen, bool new);
- Asks for a file name. The file name is returned into buffer
- 'buf' of length 'buflen' (which is zero-terminated). The
- initial content of 'buf' is used as a default file name. The
- 'new' parameter determines checks made on the file: when FALSE,
- the file must exist and be readable; when TRUE, the file must
- not exist but should be creatable, or it must be readable (and
- if it exists, the user is asked for confirmation to overwrite
- it). It is not guaranteed but very probable that a subsequent
- fopen() of the file will succeed. If the user cancels the
- interaction, the function returns FALSE and the content of 'buf'
- is undefined.
-
- void wperror(char *name);
- Shows an I/O error message based on the current value of
- 'errno' and the string 'name', possibly like the corresponding
- Unix function: "name: <cryptic error message>". The message is
- put out in a similar style as messages put out by wmessage().
-
-
- OTHER OUTPUT ROUTINES
- ---------------------
-
- This lone routine generates output which isn't associated with any
- particular window. It does not have to be called from in a drawing
- routine.
-
- void wfleep();
- Rings the "bell" on the user's terminal.
-
-
- TEXTEDIT TOOLS
- --------------
-
- These allow small sections of text (usually one or a few lines or
- paragraphs only) to be manipulated in a standard way. The text has a
- 'focus', which is used like the Macintosh text focus. All routines that
- change the text make appropriate calls to wchange(); for these to be
- effectuated the draw procedure should call tedraw() for each text edit
- struct that belongs to a given window.
-
- [ Note: these have been changed extensively. All new routines are mentioned
- below, without any comments. Sorry. ]
- TEXTEDIT *tealloc(WINDOW *win, int h, v, width);
- Allocates an empty text edit structure in the given window or
- width 'width' with its upper left corner at (h, v). It is set
- up to use the window's current text attributes. If allocation
- fails, it returns a NULL pointer.
-
- TEXTEDIT *tecreate(WINDOW *win, int h, v, right, bottom);
-
- void tefree(TEXTEDIT *te);
- Deallocates the given textedit structure.
-
- void tedestroy(TEXTEDIT *te);
-
- void tesetfocus(TEXTEDIT *te, int foc1, foc2);
- Sets the 'focus' from the position before character 'foc1' to
- the position before character 'foc2'. I.e., if foc1==foc2, the
- focus contains no characters but is an 'insert focus'. If foc2
- is larger than the number of characters in the text, it is set
- to the end of the text.
-
- void tereplace(TEXTEDIT *te, char *str);
- Replaces the characters from foc1 to foc2-1 in the text by the
- contents of string 'str'. The new focus is set after the last
- character of the inserted string. This is effectively a delete
- of 'str' is empty, or an insert if the focus is an insert focus.
-
- void tebackspace(TEXTEDIT *te);
- Deletes the focus when it contains at least a character;
- otherwise, deletes the character before the focus, if any. The
- new focus is an insert position at the first deleted character.
-
- bool teclick(TEXTEDIT *te, int h, v);
- Places the focus at the text position corresponding to the point
- (h, v). Returns FALSE if (h, v) is outside the text's
- rectangle, and then the focus is unchanged (but a position
- beyond the end of the last line selects an insert focus at the
- end of the text).
-
- bool teclicknew(TEXTEDIT *te, int h, v, bool extend);
-
- bool tedoubleclick(TEXTEDIT *tp, int h, int v);
-
- void tearrow(TEXTEDIT *te, int code);
- Performs the effect of an arrow key on the focus. In 'code' the
- code of an arrow key should be given as reported by wgetevent()
- (subsection WE_COMMAND).
-
- bool teevent(TEXTEDIT *te, EVENT *ep);
- If the event is applicable to the textedit record, executes it
- and returns TRUE, otherwise returns FALSE. Applicable events
- are (at least): WE_MOUSE_DOWN, WE_CHAR, and WE_COMMAND with
- command codes for arrows, WC_BACKSPACE and WC_RETURN. After a
- WE_MOUSE_DOWN event, this may eat subsequent WE_MOUSE_MOVE and
- a WE_MOUSE_UP event.
-
- void tedraw(TEXTEDIT *te);
- Should be called only in a draw procedure, to draw the entire
- text rectangle.
-
- void tedrawnew(TEXTEDIT *te, int left, top, right, bottom);
-
- int tegetlen(TEXTEDIT *tp);
-
- char *tegettext(TEXTEDIT *te);
- Returns a pointer to the entire text contained in the textedit
- struct. This should only be used to make a copy of the text;
- the text may float around in memory.
-
- char *tegetselection(te); [*]
- Returns a pointer to a copy of the text contained in the text
- selection. This pointer points to memory that has been
- allocated with malloc() and should eventually be freed by the
- caller with free().
-
- void temove(TEXTEDIT *te, int h, v, width);
- Moves the textedit struct to a new place in the document. The
- point (h, v) is the new top left corner, while 'width' is the
- new width.
-
- void temovenew(TEXTEDIT *tp,
- int left, int top, int right, int bottom);
-
- int tegetnlines(TEXTEDIT *te);
- Returns the number of lines contained in the textedit struct.
- This includes any line breaks inserted to make the text fit in
- the given width.
-
- int tegetfoc1(TEXTEDIT *te);
- int tegetfoc2(TEXTEDIT *te);
- These return the beginning and end of the text focus, as set by
- tesetfocus() or other calls.
-
- int tegetleft(TEXTEDIT *te);
- int tegettop(TEXTEDIT *te);
- int tegetright(TEXTEDIT *te);
- int tegetbottom(TEXTEDIT *te);
- These return the coodinates of the four corners of the
- rectangle in which the text is being displayed.
-
- void tesetbuf(TEXTEDIT *tp, char *buf, int buflen);
-
- int wdrawpar(int h, v, char *text, int width);
- Draws a paragraph of text in a rectangle with (h, v) as its top
- left corner which is 'width' wide; it is drawn exactly the same
- as when the text would have been put in a textedit struct at the
- same position. It returns the v coordinate of the bottom of the
- box in which the text is drawn.
-
- int wparheight(char *text, int width);
- Returns the height of a paragraph of text (in document
- coordinates) when it would be drawn by wdrawpar using the same
- width.
-
-